/*
* @Author: ystlong
* @Date:   2018-06-11 19:13:04
* @Last Modified by:   ystlong
* @Last Modified time: 2018-07-01 10:36:20

*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "config.h"
#include "bfd.h"
#include "dis-asm.h"

// bfd_vma, struct disassemble_info * -> void
// Formatter for address in memory referencing instructions
void override_print_address(bfd_vma addr, struct disassemble_info *info){
	// printf("%")
	if ((long)addr >= 0)
		printf("#{pc}+%ld", addr);
	else
		printf("#{pc}%ld", addr);
}

int main() {

	long pc;
	struct disassemble_info dis_info;
	struct disassemble_info *dis = &dis_info;
	bfd_byte buf[120];
	long *vma = &pc;
	int buflen = 120;
	char *disas_options = "";
	memset(&dis_info, 0, sizeof(dis_info));

    init_disassemble_info (&dis_info, stdout, (fprintf_ftype) fprintf);

    pc = 0;
    dis->buffer_vma = pc;
    dis->buffer = buf;
    dis->buffer_length = buflen;
    dis->print_address_func = override_print_address;
    // dis->disassembler_options = disas_options;
    dis->fprintf_func = fprintf;
    // dis->stream = stdout;
    // dis->arch = bfd_arch_aarch64;
    // dis->mach = bfd_mach_aarch64;
    dis->arch = bfd_arch_i386;
    dis->mach = bfd_mach_x86_64;

    // dis->endian = BFD_ENDIAN_LITTLE;
    // dis->endian_code = BFD_ENDIAN_LITTLE;
    // dis->insn_sets = ???
    // dis->section = ???
    // dis->octets_per_byte = 4;
	pc = 0;
	unsigned int mov_inst[] = {
		0xaa0203e1,
		0x14000000,
		0x17ffffff,
		0x94000002
	};

	unsigned char t_buf[] = {0x55, 0x48, 0x8d, 0x15, 0xfa, 0xec, 0x76, 0x01, 0x48, 0x89, 0xe5, 0x5d, 0xe9, 0x8f, 0x79, 0xfe, 0xff, 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x1f, 0x44, 0x00, 0x00};
	printf("len: %d\n", sizeof(t_buf));
	// dis->disassembler_needs_relocs = 1;
	// memcpy(dis->buffer, t_buf, sizeof(t_buf));
	pc = 0x7fcec70;
	dis->buffer = t_buf;
	dis->buffer_length = sizeof(t_buf);
	dis->buffer_vma = pc;
	int res = 0;
	int len = 0;
		// len = print_insn_i386(pc, &dis_info);
		// // res += len;
		// printf("i: %d, res: %d\n", i, res);
	for(int i=0; i<sizeof(t_buf); i += len) {
		len = print_insn_i386(pc+i, &dis_info);
		printf("\n");
		// res += len;
		// print 
		// printf(" i: %d, res: %d\n", i, res);
	}
	
	// for(int i=0; i < sizeof(mov_inst); i++) {
	// 	memcpy(dis->buffer, &mov_inst[i], sizeof(mov_inst[i]));
	// 	printf("aaa: %x\n", *(unsigned int*)dis->buffer);
	// 	print_insn_i386(pc, &dis_info);
	// 	// print_insn_aarch64(pc, &dis_info);
	// 	printf("\n");
	// }
    return 0;
}